#ifndef _ECXROOT_H_
#define _ECXROOT_H_

#include "ecxroot_op.h"
#include "edbroot.h"

#define ECXROOT_FOREACH_CHILD(ecxroot, sr, child)		\
	for (child = ecxroot_get_first(ecxroot, sr); child; child = ecxroot_get_next_free(ecxroot, child))

#define ECXROOT_FOREACH_CHILD_N(ecxroot, sr, child, next)	\
	for (child = ecxroot_get_first(ecxroot, sr), next = ecxroot_get_next(ecxroot, child); child; tree_unlock(child, PIN_LOCK), child = next, next = ecxroot_get_next(ecxroot, child))

#define ECXROOT_FOREACH_CHILD_RETURN(sr_child, res)	\
	do { if (edbroot_is_ontree(sr_child)) tree_unlock(sr_child, PIN_LOCK); return (res); } while (0)

#define ECXROOTV_FOREACH_CHILD(ecxroot, sr, child)		\
	for (child = ecxrootv_get_first(ecxroot, sr); child;	\
	     child = ecxrootv_get_next_free(ecxroot, child))

#define ECXROOTV_FOREACH_CHILD_RETURN	ECXROOT_FOREACH_CHILD_RETURN

sr_t *ecxroot_get_child(ecxroot_t *ecxroot, const sr_t *sr_dir, const char *name);

sr_t *ecxroot_get_first(ecxroot_t *ecxroot, const sr_t *sr_group);
sr_t *ecxroot_get_next(ecxroot_t *ecxroot, const sr_t *sr);
sr_t *ecxroot_get_next_free(ecxroot_t *ecxroot, const sr_t *sr);
sr_t *ecxroot_get_last(ecxroot_t *ecxroot, const sr_t *sr_group);
sr_t *ecxroot_get_prev(ecxroot_t *ecxroot, const sr_t *sr);
sr_t *ecxroot_get_deref(ecxroot_t *ecxroot, const sr_t *sr);

sr_t *ecxrootv_get_first(ecxroot_t *ecxroot, const sr_t *sr_group);
sr_t *ecxrootv_get_next_free(ecxroot_t *ecxroot, const sr_t *sr);

edb_err_t ecxroot_set_val(ecxroot_t *ecxroot, sr_t *sr, sr_val_t val);
edb_err_t ecxroot_set_ref(ecxroot_t *ecxroot, sr_t *sr, sr_t *sr_LNP);
edb_err_t ecxroot_set_target(ecxroot_t *ecxroot, sr_t *sr, const sr_t *sr_target);
edb_err_t ecxroot_set_val_PE(ecxroot_t *ecxroot, sr_t *sr, sr_val_t val);

sr_t *ecxroot_dup(ecxroot_t *ecxroot, const sr_t *sr_src);

sr_t *ecxroot_xecreate(ecxroot_t *ecxroot, sr_t *sr_HMS, const char *name, srt_t srt);
ECMBOOL ecxroot_xedelete(ecxroot_t *ecxroot, sr_t *sr_xe, ECMBOOL force);
sr_t *ecxroot_xeappend(ecxroot_t *ecxroot, sr_t *sr_HMS, sr_t *sr_xe_SA);

ECMBOOL ecxroot_exist(ecxroot_t *ecxroot, const sr_t *sr_group, const char *name);

int ecxroot_get_num_child(ecxroot_t *ecxroot, const sr_t *sr_group);

void ecxroot_release(ecxroot_t *ecxroot, sr_t *sr, ECMBOOL from_get);

#endif
